<?php
/**
 * ZFramework project
 *
 * @author liumingl@hotmail.com
 * @version
 */
define('DS', DIRECTORY_SEPARATOR);
define('PS', PATH_SEPARATOR);
define('BP', dirname(dirname(__FILE__)));

define('CONTROLLERS_DIR', BP . '/application/');

/**
 *
 */
$paths[] = BP . DS . 'application';
$paths[] = 'D:\htdocs\ZendFramework-1.6.0RC1\library';
//$paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core';

$app_path = implode(PS, $paths);

set_include_path($app_path . PS . get_include_path());

require_once BP . '/application/include/functions.php';
require_once 'Zend/Loader.php';

/**
 *
 * @author liumingl@hotmail.com
 */
final class zfproject
{
	/**
	 * _config
	 *
	 * @var Zend_Config
	 * @access private
	 */
	private $_config = null;
	
	/**
	 * _dbAdapter
	 *
	 * @var Zend_Db
	 * @access private
	 */
	private $_dbAdapter = null;
	
	/**
	 * _locale
	 *
	 * @var Zend_Locale
	 * @access private
	 */
	private $_locale = null;
	
	/**
	 * _cache
	 *
	 * @var Zend_Cache
	 * @access private
	 */
	private $_cache = null;
	
	/**
	 * _log
	 *
	 * @var Zend_Log
	 * @access private
	 */
	private $_log = null;
	
	/**
	 * _frontCtrl
	 *
	 * @var Zend_Controller_Front
	 * @access private
	 */
	private $_frontCtrl = null;
	
	private static $_registry = array();
	/**
	 * _instance
	 *
	 * @static
	 * @access private
	 */
	private static $_instance = null;
	
	public static function getInstance ()
	{
		$className = __CLASS__;
		if (! (self::$_instance instanceof self)) {
			self::$_instance = new $className();
			self::$_instance->_init();
			self::$_instance->_buildDbAdapter();
			self::$_instance->_buildSession();
			self::$_instance->_buildLocale();
			self::$_instance->_buildLog();
			self::$_instance->_buildFrontCtrl();
		}
		
		return self::$_instance;
	}
	/**
	 * _init
	 *
	 * @access private
	 * @return void
	 */
	private function _init ()
	{
		/**
		 *
		 */
		Zend_Loader::registerAutoload();
		
		$this->_buildConfig();
		
		/**
		 *
		 */
		error_reporting($this->_config->error->reporting);
		
		$this->_buildCache();
		
		// bootstrap layouts
		//Zend_Layout::startMvc(array('layoutPath' => '../application/default/layouts' , 'layout' => 'main'));
	
	}
	
	/**
	 * _buildConfig
	 *
	 * @access private
	 * @return Zend_Config_Xml
	 */
	private function _buildConfig ()
	{
		/**
		 *
		 */
		//set_exception_handler('error_Exception_handler');
		
		if (! ($this->_config instanceof Zend_Config_Ini)) {
			$this->_config = new Zend_Config_Xml(BP . '/config/config.xml', 'development');
		}
		
		Zend_Registry::set('config', $this->_config);
		
		return $this->_config;
	}
	
	private function _buildDbAdapter()
	{
		$this->_dbAdapter = Zend_Db::factory($this->_config->database->adapter, $this->_config->database->params);
		$this->_dbAdapter->query('SET NAMES ' . $this->_config->database->charset);
		
		Zend_Db_Table::setDefaultAdapter($this->_dbAdapter);
		
		Zend_Registry::set('dbAdapter', $this->_dbAdapter);
	}
	
	/**
	 * _buildSession
	 *
	 * @access private
	 * @return void
	 */
	private function _buildSession()
	{
		
	}
	
	/**
	 * _buildLocale
	 *
	 * @access private
	 * @return
	 */
	private function _buildLocale()
	{
		$this->_locale = new Zend_Locale($this->_config->locale);

		Zend_Registry::set('locale', $this->_locale);
		return $this->_locale;
	}
	/**
	 * _buildCache
	 *
	 * @access private
	 * @return Zend_Cache
	 */
	private function _buildCache ()
	{
		if (!($this->_cache instanceof Zend_Cache ))
		{
			$frontend_name = $this->_config->cache->frontend->name;
			$backend_name = $this->_config->cache->backend->name;
			
			$frontendAttributes = $this->_config->cache->frontend->toArray();
			unset($frontendAttributes['name']);
			$backendAttributes = $this->_config->cache->backend->toArray();
			$backendAttributes['cache_dir'] = BP . '/' . $backendAttributes['cache_dir'];
			unset($backendAttributes['name']);
			
			
			$this->_cache = Zend_Cache::factory($frontend_name, $backend_name, $frontendAttributes, $backendAttributes);
		}
		
		Zend_Registry::set('cache', $this->_cache);
		
		return $this->_cache;
	}
	
	private function _buildLog()
	{
		if (!($this->_log instanceof Zend_Log))
		{
			$format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
            $formatter = new Zend_Log_Formatter_Simple($format);
            $writer = new Zend_Log_Writer_Stream($this->_config->log->filename);
            $writer->setFormatter($formatter);
            $this->_log = new Zend_Log($writer);
		}
		
		Zend_Registry::set('log', $this->_log);
		
		return $this->_log;
	}
	
	/**
	 * _buildFrontCtrl
	 *
	 * @access private
	 * @return Zend_Controller_Front
	 */
	private function _buildFrontCtrl()
	{
		$this->_frontCtrl = Zend_Controller_Front::getInstance();
		$this->_frontCtrl->throwExceptions($this->_config->error->throwExceptions);

		$module = $this->_config->module->toArray();
		
		foreach($module as $key => $value)
        {
            $module[$key] = CONTROLLERS_DIR . DS . $key . DS . $value;
            $model[] = CONTROLLERS_DIR . DS . $key . DS . 'models';
        }
        
        $add_path = implode(PS, $model);
		set_include_path($add_path . PS . get_include_path());
		
		$this->_frontCtrl->setParam('useDefaultControllerAlways',true);
        $this->_frontCtrl->setControllerDirectory( $module );
		$this->_frontCtrl->registerPlugin(new Zend_Controller_Plugin_ErrorHandler());
		
        return $this->_frontCtrl;
	}
	
	/**
	 * run
	 *
	 * @access public
	 * @return void
	 */
	public function run()
	{
		$this->_frontCtrl->dispatch();
	}
}

$zf = zfproject::getInstance();
$zf->run();